namespace Microsoft.VisualStudio.EnterpriseTools.OperationDesigner
{
    using Microsoft.VisualStudio.VirtualTreeGrid;
    using System;
    using System.Collections;
    using System.ComponentModel.Design;
    using System.Runtime.CompilerServices;
    using System.Windows.Forms;

    public sealed class AggregateBranch : IBranch, IMultiColumnBranch, IOperationDesignerBranch
    {
        private ArrayList branchList;
        private IBranch primaryBranch;
        private bool readOnly;

        public event BranchModificationEventHandler OnBranchModification;

        public AggregateBranch(IList branchList, int primaryBranchIndex)
        {
            if (branchList == null)
            {
                throw new ArgumentNullException("branchList");
            }
            this.primaryBranch = (IBranch) branchList[primaryBranchIndex];
            this.branchList = new ArrayList(branchList.Count);
            foreach (object obj2 in branchList)
            {
                IBranch branch = obj2 as IBranch;
                if (branch == null)
                {
                    throw new ArgumentException("branchList");
                }
                this.branchList.Add(branch);
                branch.OnBranchModification += new BranchModificationEventHandler(this.OnInnerBranchModification);
            }
        }

        private IBranch FindBranchForRow(ref int row)
        {
            int num = 0;
            int num2 = row;
            foreach (IBranch branch in this.branchList)
            {
                int visibleItemCount = branch.VisibleItemCount;
                num += visibleItemCount;
                if (num2 < num)
                {
                    return branch;
                }
                row -= visibleItemCount;
            }
            throw new ArgumentOutOfRangeException("row");
        }

        private int FindIndexForBranch(IBranch innerBranch, int index)
        {
            int num = index;
            foreach (IBranch branch in this.branchList)
            {
                if (branch == innerBranch)
                {
                    return num;
                }
                num += branch.VisibleItemCount;
            }
            throw new ArgumentException("innerBranch");
        }

        public int GetJaggedColumnCount(int row)
        {
            IBranch branch = this.FindBranchForRow(ref row);
            if (branch is IMultiColumnBranch)
            {
                return ((IMultiColumnBranch) branch).GetJaggedColumnCount(row);
            }
            return 1;
        }

        void IOperationDesignerBranch.EndInsert(int row)
        {
            IBranch branch = this.FindBranchForRow(ref row);
            if (branch is IOperationDesignerBranch)
            {
                ((IOperationDesignerBranch) branch).EndInsert(row);
            }
        }

        CommandID IOperationDesignerBranch.GetDefaultAction(int row)
        {
            IBranch branch = this.FindBranchForRow(ref row);
            if (branch is IOperationDesignerBranch)
            {
                return ((IOperationDesignerBranch) branch).GetDefaultAction(row);
            }
            return null;
        }

        OperationDesignerValueSupportedStates IOperationDesignerBranch.GetValueSupported(int row, int column)
        {
            IBranch branch = this.FindBranchForRow(ref row);
            if (branch is IOperationDesignerBranch)
            {
                return ((IOperationDesignerBranch) branch).GetValueSupported(row, column);
            }
            return OperationDesignerValueSupportedStates.Unsupported;
        }

        void IOperationDesignerBranch.InsertCreatorNode(int row, int creatorNodeIndex)
        {
            IBranch branch = this.FindBranchForRow(ref row);
            if (branch is IOperationDesignerBranch)
            {
                ((IOperationDesignerBranch) branch).InsertCreatorNode(row, creatorNodeIndex);
            }
        }

        ProcessKeyResult IOperationDesignerBranch.ProcessKeyDown(int row, int column, KeyEventArgs e)
        {
            IBranch branch = this.FindBranchForRow(ref row);
            if (branch is IOperationDesignerBranch)
            {
                return ((IOperationDesignerBranch) branch).ProcessKeyDown(row, column, e);
            }
            return new ProcessKeyResult();
        }

        ProcessKeyResult IOperationDesignerBranch.ProcessKeyPress(int row, int column, char keyPressed, Keys modifiers)
        {
            IBranch branch = this.FindBranchForRow(ref row);
            if (branch is IOperationDesignerBranch)
            {
                return ((IOperationDesignerBranch) branch).ProcessKeyPress(row, column, keyPressed, modifiers);
            }
            return new ProcessKeyResult();
        }

        VirtualTreeLabelEditData IBranch.BeginLabelEdit(int row, int column, VirtualTreeLabelEditActivationStyles activationStyle)
        {
            return this.FindBranchForRow(ref row).BeginLabelEdit(row, column, activationStyle);
        }

        LabelEditResult IBranch.CommitLabelEdit(int row, int column, string newText)
        {
            return this.FindBranchForRow(ref row).CommitLabelEdit(row, column, newText);
        }

        VirtualTreeAccessibilityData IBranch.GetAccessibilityData(int row, int column)
        {
            return this.FindBranchForRow(ref row).GetAccessibilityData(row, column);
        }

        VirtualTreeDisplayData IBranch.GetDisplayData(int row, int column, VirtualTreeDisplayDataMasks requiredData)
        {
            return this.FindBranchForRow(ref row).GetDisplayData(row, column, requiredData);
        }

        object IBranch.GetObject(int row, int column, ObjectStyle style, ref int options)
        {
            return this.FindBranchForRow(ref row).GetObject(row, column, style, ref options);
        }

        string IBranch.GetText(int row, int column)
        {
            return this.FindBranchForRow(ref row).GetText(row, column);
        }

        string IBranch.GetTipText(int row, int column, ToolTipType tipType)
        {
            return this.FindBranchForRow(ref row).GetTipText(row, column, tipType);
        }

        bool IBranch.IsExpandable(int row, int column)
        {
            return this.FindBranchForRow(ref row).IsExpandable(row, column);
        }

        LocateObjectData IBranch.LocateObject(object obj, ObjectStyle style, int locateOptions)
        {
            LocateObjectData data = new LocateObjectData();
            data.Row = -1;
            foreach (IBranch branch in this.branchList)
            {
                data = branch.LocateObject(obj, style, locateOptions);
                if (data.Row != -1)
                {
                    return data;
                }
            }
            return data;
        }

        void IBranch.OnDragEvent(object sender, int row, int column, DragEventType eventType, DragEventArgs args)
        {
            this.FindBranchForRow(ref row).OnDragEvent(sender, row, column, eventType, args);
        }

        void IBranch.OnGiveFeedback(GiveFeedbackEventArgs args, int row, int column)
        {
            this.FindBranchForRow(ref row).OnGiveFeedback(args, row, column);
        }

        void IBranch.OnQueryContinueDrag(QueryContinueDragEventArgs args, int row, int column)
        {
            this.FindBranchForRow(ref row).OnQueryContinueDrag(args, row, column);
        }

        VirtualTreeStartDragData IBranch.OnStartDrag(object sender, int row, int column, DragReason reason)
        {
            return this.FindBranchForRow(ref row).OnStartDrag(sender, row, column, reason);
        }

        StateRefreshChanges IBranch.SynchronizeState(int row, int column, IBranch matchBranch, int matchRow, int matchColumn)
        {
            return this.FindBranchForRow(ref row).SynchronizeState(row, column, matchBranch, matchRow, matchColumn);
        }

        StateRefreshChanges IBranch.ToggleState(int row, int column)
        {
            return this.FindBranchForRow(ref row).ToggleState(row, column);
        }

        SubItemCellStyles IMultiColumnBranch.ColumnStyles(int column)
        {
            if (this.primaryBranch is IMultiColumnBranch)
            {
                return ((IMultiColumnBranch) this.primaryBranch).ColumnStyles(column);
            }
            return SubItemCellStyles.Simple;
        }

        private void OnInnerBranchModification(object sender, BranchModificationEventArgs args)
        {
            if (this.OnBranchModification != null)
            {
                args.Index = this.FindIndexForBranch(args.Branch, args.Index);
                args.Branch = this;
                this.OnBranchModification(this, args);
            }
        }

        public int ColumnCount
        {
            get
            {
                if (this.primaryBranch is IMultiColumnBranch)
                {
                    return ((IMultiColumnBranch) this.primaryBranch).ColumnCount;
                }
                return 1;
            }
        }

        bool IOperationDesignerBranch.ReadOnly
        {
            get
            {
                return this.readOnly;
            }
            set
            {
                this.readOnly = value;
            }
        }

        BranchFeatures IBranch.Features
        {
            get
            {
                return this.primaryBranch.Features;
            }
        }

        int IBranch.UpdateCounter
        {
            get
            {
                return this.primaryBranch.UpdateCounter;
            }
        }

        public int VisibleItemCount
        {
            get
            {
                int num = 0;
                foreach (IBranch branch in this.branchList)
                {
                    num += branch.VisibleItemCount;
                }
                return num;
            }
        }
    }
}

